package com.my.controller;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonSerializer;
import com.my.pojo.Address;
import com.my.pojo.Business;
import com.my.pojo.Goods;
import com.my.pojo.Orders;
import com.my.pojo.Stock;
import com.my.pojo.User;
import com.my.service.IOrdersService;
import com.my.util.JWTUtils;
import com.my.util.UserJWTUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@CrossOrigin("*")
@RequestMapping("/orders")
public class OrdersController {
    private IOrdersService iOrdersService;

    @Autowired
    public void setIOrdersService(IOrdersService iOrdersService) {
        this.iOrdersService = iOrdersService;
    }

    private String ordersToJson(List<Orders> ordersList) {
        JsonArray jsonArray = new JsonArray();
        ordersList.forEach(e -> {
            if (e.getStatus() != -1) {
                JsonObject jsonObject = new JsonObject();

                jsonObject.addProperty("ordersId", e.getOrderId());
                SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                jsonObject.addProperty("date", f.format(e.getDate()));
                jsonObject.addProperty("logistics", e.getLogistics());
                jsonObject.addProperty("type", e.getType());
                jsonObject.addProperty("num", e.getGoodsNum());
                jsonObject.addProperty("status", e.getStatus());

                jsonArray.add(jsonObject);
            }
        });
        return jsonArray.toString();
    }

    private String ordersToJson(Orders orders) {
        JsonObject jsonObject = new JsonObject();

        jsonObject.addProperty("ordersId", orders.getOrderId());
        SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        jsonObject.addProperty("date", f.format(orders.getDate()));
        jsonObject.addProperty("logistics", orders.getLogistics());
        jsonObject.addProperty("type", orders.getType());
        jsonObject.addProperty("num", orders.getGoodsNum());
        jsonObject.addProperty("status", orders.getStatus());

        return jsonObject.toString();
    }

    private String addressToJSON(List<Address> addressList) {
        JsonArray jsonArray = new JsonArray();
        addressList.forEach(e -> {
            if (e != null) {
                if (e.getStatus() != -1) {
                    JsonObject jsonObject = new JsonObject();
                    jsonObject.addProperty("addressId", e.getAddress_id());
                    jsonObject.addProperty("province", e.getProvince());
                    jsonObject.addProperty("city", e.getCity());
                    jsonObject.addProperty("district", e.getDistrict());
                    jsonObject.addProperty("address", e.getAddress());
                    jsonObject.addProperty("code", e.getCode());
                    jsonObject.addProperty("phone", e.getPhone());
                    jsonObject.addProperty("name", e.getName());
                    jsonObject.addProperty("status", e.getStatus());
                    jsonArray.add(jsonObject);
                }
            } else {
                jsonArray.add("null");
            }

        });
        return jsonArray.toString();
    }

    private String addressToJSON(Address address) {
        JsonObject jsonObject = new JsonObject();
        if (address != null) {
            jsonObject.addProperty("addressId", address.getAddress_id());
            jsonObject.addProperty("province", address.getProvince());
            jsonObject.addProperty("city", address.getCity());
            jsonObject.addProperty("district", address.getDistrict());
            jsonObject.addProperty("address", address.getAddress());
            jsonObject.addProperty("code", address.getCode());
            jsonObject.addProperty("phone", address.getPhone());
            jsonObject.addProperty("name", address.getName());
            jsonObject.addProperty("status", address.getStatus());
        } else {
            return "";
        }

        return jsonObject.toString();
    }

    private String goodsToJSON(List<Goods> goodsList) {
        JsonArray jsonArray = new JsonArray();
        goodsList.forEach(e -> {
            JsonObject jsonObject = new JsonObject();
            jsonObject.addProperty("goodsId", e.getGoodsId());
            jsonObject.addProperty("name", e.getName());
            jsonObject.addProperty("price", e.getPrice());
            jsonObject.addProperty("img", e.getImgUrl());
            jsonObject.addProperty("stock", e.getStock());
            jsonObject.addProperty("info", e.getInfo());
            jsonObject.addProperty("status", e.getStatus());
            jsonArray.add(jsonObject);
        });
        return jsonArray.toString();
    }

    private String goodsToJSONWithOutImg(List<Goods> goodsList) {
        JsonArray jsonArray = new JsonArray();
        goodsList.forEach(e -> {
            JsonObject jsonObject = new JsonObject();
            jsonObject.addProperty("goodsId", e.getGoodsId());
            jsonObject.addProperty("name", e.getName());
            jsonObject.addProperty("price", e.getPrice());
            jsonObject.addProperty("stock", e.getStock());
            jsonObject.addProperty("info", e.getInfo());
            jsonObject.addProperty("status", e.getStatus());
            jsonArray.add(jsonObject);
        });
        return jsonArray.toString();
    }


    private String goodsToJSON(Goods goods) {
        JsonObject jsonObject = new JsonObject();
        jsonObject.addProperty("goodsId", goods.getGoodsId());
        jsonObject.addProperty("name", goods.getName());
        jsonObject.addProperty("price", goods.getPrice());
        jsonObject.addProperty("img", goods.getImgUrl());
        jsonObject.addProperty("stock", goods.getStock());
        jsonObject.addProperty("info", goods.getInfo());
        jsonObject.addProperty("status", goods.getStatus());
        return jsonObject.toString();
    }

    private String businessToJSON(List<Business> businessList) {
        JsonArray jsonArray = new JsonArray();
        businessList.forEach(src -> {
            JsonObject jsonObject = new JsonObject();
            jsonObject.addProperty("shopName", src.getShopName());
            jsonArray.add(jsonObject);
        });

        return jsonArray.toString();
    }

    private String businessToJSON(Business business) {
        JsonObject jsonObject = new JsonObject();
        jsonObject.addProperty("shopName", business.getShopName());

        return jsonObject.toString();
    }

    private String userJSON(List<User> userList) {
        JsonArray jsonArray = new JsonArray();
        userList.forEach(src -> {
            JsonObject jsonObject = new JsonObject();
            jsonObject.addProperty("username", src.getUsername());
            jsonObject.addProperty("phone", src.getPhone());
            jsonObject.addProperty("email", src.getEmail());
            jsonArray.add(jsonObject);
        });

        return jsonArray.toString();
    }

    private void putMessage(Map<String, String> map, String code, String message) {
        map.put("code", code);
        map.put("message", message);
    }

    @RequestMapping("/send")
    public String sendOrders(Integer ordersId, HttpServletRequest req) {
        Map<String, String> map = new HashMap<>();
        Integer businessId = JWTUtils.getId(req.getHeader("token"));
        if (businessId == null) {
            putMessage(map, "400", "token解析错误");
        } else {
            if (ordersId <= 0) {
                putMessage(map, "orders_500", "error id");
            } else {
                Integer flag = iOrdersService.sendOrders(ordersId, businessId);
                if (flag == 0) {
                    putMessage(map, "orders_200", "success");
                } else if (flag == -1) {
                    putMessage(map, "orders_501", "no order");
                } else if (flag == -2) {
                    putMessage(map, "orders_502", "has send");
                } else if (flag == -3) {
                    putMessage(map, "order_503", "sql error");
                } else if (flag == -4) {
                    putMessage(map, "orders_504", "非法操作");
                }
            }
        }


        return new Gson().toJson(map);
    }

    @RequestMapping("/delete")
    public String deleteOrders(Integer ordersId, HttpServletRequest req) {
        Map<String, String> map = new HashMap<>();

        Integer businessId = JWTUtils.getId(req.getHeader("token"));
        if (businessId == null) {
            putMessage(map, "400", "token解析错误");
        } else {
            if (ordersId <= 0) {
                putMessage(map, "orders_500", "error id");
            } else {
                Integer flag = iOrdersService.deleteOrders(ordersId, businessId);
                if (flag == 0) {
                    putMessage(map, "orders_200", "success");
                } else if (flag == -1) {
                    putMessage(map, "orders_501", "no order");
                } else if (flag == -2) {
                    putMessage(map, "order_502", "sql error");
                } else if (flag == -3) {
                    putMessage(map, "orders_503", "非法操作");
                }
            }
        }


        return new Gson().toJson(map);
    }

    @RequestMapping("/addOrdersLogistics")
    String addOrdersLogistics(Integer ordersId, String logistics, HttpServletRequest req) {
        Map<String, String> map = new HashMap<>();
        Integer businessId = JWTUtils.getId(req.getHeader("token"));

        if (businessId == null) {
            putMessage(map, "400", "token解析错误");
        } else if (ordersId <= 0) {
            putMessage(map, "orders_500", "error id");
        } else {
            Integer flag = iOrdersService.addOrdersLogistics(ordersId, logistics, businessId);
            if (flag == 0) {
                putMessage(map, "orders_200", "success");
            } else if (flag == -1) {
                putMessage(map, "orders_501", "no order");
            } else if (flag == -2) {
                putMessage(map, "order_502", "not send");
            } else if (flag == -3) {
                putMessage(map, "order_503", "sql error");
            } else if (flag == -4) {
                putMessage(map, "order_504", "非法请求");
            }
        }

        return new Gson().toJson(map);
    }

    @RequestMapping("/showForBusiness")
    public String showAll(String context,
                          Integer currentPage,
                          Integer pageSize,
                          String sort,
                          Boolean asc,
                          HttpServletRequest req) {
        Map<String, String> map = new HashMap<>();
        String token = req.getHeader("token");
        Integer businessId = JWTUtils.getId(token);
        if (businessId == null) {
            putMessage(map, "400", "token解析失败");
        } else {
            Pageable pageable;
            if (!"".equals(sort)) {
                Sort.Order order = new Sort.Order((asc ? Sort.Direction.ASC : Sort.Direction.DESC), sort);
                Sort s = new Sort(order);
                pageable = new PageRequest(currentPage, pageSize, s);
            } else {
                pageable = new PageRequest(currentPage, pageSize);
            }

            Page<Orders> ordersPage = this.iOrdersService.showAllOrders(pageable, context, businessId);
            if (ordersPage == null) {
                this.putMessage(map, "500", "error");
            } else {
                this.putMessage(map, "200", "success");
                map.put("totalNum", ordersPage.getTotalElements() + "");
                map.put("totalPages", ordersPage.getTotalPages() + "");
                List<Orders> ordersList = ordersPage.getContent();
                map.put("orders", ordersToJson(ordersList));

                List<Goods> goodsList = new ArrayList<>();
                List<Address> addressList = new ArrayList<>();
                List<User> userList = new ArrayList<>();
                ordersList.forEach(e -> {
                    goodsList.add(e.getGoods());
                    addressList.add(e.getAddress());
                    userList.add(e.getUser());
                });

                map.put("goods", goodsToJSONWithOutImg(goodsList));
                map.put("address", addressToJSON(addressList));
                map.put("user", userJSON(userList));
            }
        }
        return new Gson().toJson(map);
    }

    @RequestMapping("/showForUser")
    public String showAllForUser(String context,
                                 Integer currentPage,
                                 Integer pageSize,
                                 String sort,
                                 Boolean asc,
                                 HttpServletRequest req) {
        Map<String, String> map = new HashMap<>();
        String token = req.getHeader("token");
        Integer userId = UserJWTUtils.getId(token);
        if (userId == null) {
            putMessage(map, "400", "token解析失败");
        } else {
            Pageable pageable;
            if (!"".equals(sort)) {
                Sort.Order order = new Sort.Order((asc ? Sort.Direction.ASC : Sort.Direction.DESC), sort);
                Sort s = new Sort(order);
                pageable = new PageRequest(currentPage, pageSize, s);
            } else {
                pageable = new PageRequest(currentPage, pageSize);
            }

            Page<Orders> ordersPage = this.iOrdersService.showAllOrdersForUser(pageable, context, userId);
            if (ordersPage == null) {
                this.putMessage(map, "500", "error");
            } else {
                this.putMessage(map, "200", "success");
                map.put("totalNum", ordersPage.getTotalElements() + "");
                map.put("totalPages", ordersPage.getTotalPages() + "");
                List<Orders> ordersList = ordersPage.getContent();
                map.put("orders", ordersToJson(ordersList));

                List<Goods> goodsList = new ArrayList<>();
                List<Address> addressList = new ArrayList<>();
                List<Business> businessList = new ArrayList<>();
                ordersList.forEach(e -> {
                    goodsList.add(e.getGoods());
                    addressList.add(e.getAddress());
                    businessList.add(e.getBusiness());
                });

                map.put("goods", goodsToJSON(goodsList));
                map.put("address", addressToJSON(addressList));
                map.put("business", businessToJSON(businessList));
            }
        }
        return new Gson().toJson(map);
    }

    @RequestMapping("/showOne")
    public String showOrderForUser(Integer ordersId, HttpServletRequest req) {
        Map<String, String> map = new HashMap<>();

        Integer userId = UserJWTUtils.getId(req.getHeader("token"));
        if (userId == null) {
            putMessage(map, "400", "token解析失败");
        } else {
            Orders orders = iOrdersService.showOneOrder(ordersId, userId);

            if (orders != null && orders.getType() == 0) {
                putMessage(map, "200", "Success");
                map.put("orders", ordersToJson(orders));
                map.put("business", businessToJSON(orders.getBusiness()));
                map.put("goods", goodsToJSON(orders.getGoods()));
                map.put("address", addressToJSON(orders.getAddress()));
            } else {
                putMessage(map, "500", "error");
            }

        }
        return new Gson().toJson(map);
    }

    @RequestMapping("/add")
    public String addOrders(Integer goodsNum, Integer goodsId, HttpServletRequest req) {
        Map<String, String> map = new HashMap<>();

        if (goodsNum <= 0) {
            putMessage(map, "500", "参数错误");
        } else {
            Integer userId = UserJWTUtils.getId(req.getHeader("token"));
            if (userId == null) {
                putMessage(map, "400", "token解析错误");
            } else {
                Orders orders = new Orders();
                orders.setDate(new Date());
                orders.setStatus(0);
                orders.setType(0);
                orders.setGoodsNum(goodsNum);
                Goods goods = new Goods();
                goods.setGoodsId(goodsId);
                orders.setGoods(goods);

                User user = new User();
                user.setUserId(userId);
                orders.setUser(user);

                Integer res = iOrdersService.addOrder(orders, goodsId);
                if (res > 0) {
                    putMessage(map, "200", "Success");
                    map.put("id", res.toString());
                } else {
                    putMessage(map, "500", "error");
                }
            }
        }

        return new Gson().toJson(map);
    }

    @RequestMapping("/addAddress")
    public String addAddress(Integer ordersId, Integer addressId, HttpServletRequest req) {
        Map<String, String> map = new HashMap<>();

        Integer userId = UserJWTUtils.getId(req.getHeader("token"));
        if (userId == null) {
            putMessage(map, "400", "token解析失败");
        } else {
            Integer res = iOrdersService.addAddress(ordersId, addressId, userId);
            if (res == 1) {
                putMessage(map, "200", "Success");
            } else if (res == -1) {
                putMessage(map, "500", "订单不存在");
            } else if (res == -2) {
                putMessage(map, "501", "非法操作");
            } else if (res == -3) {
                putMessage(map, "503", "sql错误");
            } else {
                putMessage(map, "555", "未知错误");
            }
        }
        return new Gson().toJson(map);
    }

    @RequestMapping("/confirm")
    public String confirmGet(Integer ordersId, HttpServletRequest req) {
        Map<String, String> map = new HashMap<>();

        Integer userId = UserJWTUtils.getId(req.getHeader("token"));
        if (userId == null) {
            putMessage(map, "400", "token解析失败");
        } else {
            Integer res = iOrdersService.confirm(ordersId, userId);
            if(res == 1) {
                putMessage(map, "200", "success");
            } else {
                putMessage(map, "500", "error");
            }
        }
        return new Gson().toJson(map);
    }
}
